package com.bungarus.busi;

import com.bungarus.Access;
import com.bungarus.codec.protobuf.MessageProtobuf;
import com.bungarus.model.MessageBuilder;
import com.bungarus.model.MessageType;
import com.bungarus.model.Session;
import com.bungarus.model.SessionContainer;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.log4j.Logger;

import java.net.InetSocketAddress;

/**
 * Created by tang on 2018/11/19.
 */
public class ServerMediaHandler extends ChannelInboundHandlerAdapter {
    Logger logger = Logger.getLogger(ServerMediaHandler.class);
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        InetSocketAddress localAddress = (InetSocketAddress)ctx.channel().localAddress();
        if(msg instanceof MessageProtobuf.Message){
            MessageProtobuf.Message message = (MessageProtobuf.Message)msg;
            if(MessageType.HEARTBEAT_PING == message.getHeader().getType()){
                //send back pong
                logger.info("header of session or status messages from access layer: " + message.getHeader().toString());
                logger.info("body of session or status messages form access layer: " + message.getBody().toString());
                ctx.writeAndFlush(MessageBuilder.buildHeartbeatPongMessage(message.getHeader().getId()));
            }
            else if(Access.PORT_7800 == localAddress.getPort()){
                //get message from busi layer, so redirect the message to the client
                SessionContainer sessionContainer = Access.getSessionContainer();
                Session session = sessionContainer.findSession(message.getHeader().getSessionId());
                Channel channel = sessionContainer.find(session);
                //send message to client
                channel.writeAndFlush(message).addListener(channelFuture -> {
                    if(channelFuture.isSuccess()){
                        //send ack message back to busi
                        ctx.writeAndFlush(MessageBuilder.buildAckMessage(message.getHeader().getId()));
                        //waiting for client's ack
                        DischargeQueue dischargeQueue = Discharger.getQueueInstance(Discharger.DISCHARGE_NAME_CLIENT);
                        dischargeQueue.addToQueue(message);
                    }
                });
            }
        }
        else {
            super.channelRead(ctx, msg);
        }
    }
}
